#include "mqtthandler.h"
#include <QTimer>
#include <qmqtt_client.h>

//订阅发送数据
//重定义了四个主题
#define TOPIC_DATA_UP       "/app/data/up"//数据接收up modbus
#define TOPIC_DATA_DOWN     "/app/data/down"//命令控制down
#define TOPIC_CTL_UP        "/app/control/up"//数据接收up stm32
#define TOPIC_CTL_DOWN      "/app/control/down"//命令控制down

MqttHandler::MqttHandler(QObject *parent) : QObject(parent)
{
    //创建了一个QMQTT::Client的实例,用于客户端的链接
    client = new QMQTT::Client();
    //设置客户端的ID为“home-app”
    client->setClientId("home-app");

    //连接信号槽，客户端连接成功调用doConnected槽函数
    connect(client, SIGNAL(connected()), this, SLOT(doConnected()));

    //订阅主题成功信号槽函数
    connect(client, SIGNAL(subscribed(QString, quint8)),
            this, SLOT(doSubscribed(QString, quint8)));

    //客户接受到消息时，触发receive信号
    connect(client,SIGNAL(received(QMQTT::Message)),
            this,SLOT(doDataReceived(QMQTT::Message)));
}


//连接到MQTT服务器的函数
void MqttHandler::connectToHost()
{
    //client->connectToHost建立连接
    client->connectToHost();

    //3s后检测一下连接状态
    QTimer::singleShot(3000, this, SLOT(detectState()));
}

//检测MQTT客户端的连接状态
void MqttHandler::detectState()
{
    //获取连接状态
    int state = client->connectionState();
    if(state != 2)  //STATE_CONNECTED引用不到，很奇怪
    {
        qDebug()<<"mqtt connect error";
    }
}

/**
 * @brief 连接以后再订阅相关的主题
 */

//这个函数在MQTT客户端成功连接到服务器后被调用
void MqttHandler::doConnected()
{
    //输出连接成功的消息
    qDebug()<<"connect ok";
    //订阅两个主题
    client->subscribe(TOPIC_DATA_UP);
    client->subscribe(TOPIC_CTL_UP);
    //client->subscribe("data");
}
//在成功订阅一个MQTT主题后被调用，输出订阅成功的信息
void MqttHandler::doSubscribed(const QString& topic, const quint8 qos)
{
    qDebug()<<"subscribed ok, topic="<<topic;
}


//在接收到MQTT消息时被调用，输出消息主题和内容，并给出相应的信号
void MqttHandler::doDataReceived(QMQTT::Message message)
{

    //输出消息的主题和消息内容
    qDebug()<<"topic="<<QString(message.topic());
    qDebug()<<"payload="<<QString(message.payload());

    //根据主题类型TOPIC_DATA_UP或TOPIC_CTL_UP发出信号
    if(message.topic() == TOPIC_DATA_UP){
        qDebug()<<"data up topic";
        emit dataUpSignal(message.payload());//modbus数据发送信号
        qDebug()<<"data up";
    }
    else if(message.topic() == TOPIC_CTL_UP){
        qDebug()<<"ctrl up topic";
        emit ctrlUpSignal(message.payload());//stm32数据发送信号
    }
}


//发布MQTT消息
quint16 MqttHandler::publish(const QMQTT::Message &message)
{
    client->publish(message);
    //qDebug()<<"信号接收到了";
}

